﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reborn_WorldServer.App1AppHandler.Spells.Interfaces;
using App1AppHandler;
using System.Drawing;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_LightningAll : TargetSpell, IInstantCast
    {

        private int DamageLow = 200;
        private int DamageHigh = 300;

        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, false, out MapItemsWithin12) == false)
                return;

            mainCast(myCreatureBase);
        }

        private void mainCast(CreatureBase castingCreature)
        {
            List<Point> hiddenList = CreatureAI.FindHidden(castingCreature, castingCreature.currentMapItem.mapItemsWithin4, false);

            List<CreatureBase> creaturesToEffect = new List<CreatureBase>();

            List<MapItem> animateMapItems = new List<MapItem>();
            foreach (MapItem mapItem in castingCreature.currentMapItem.mapItemsWithin4)
            {
                if (CreatureAI.isHidden(mapItem.MapX, mapItem.MapY, hiddenList) == false)
                {
                    bool foundCreature = false;
                    foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                    {
                        if (creatureBase.HP > 0 &&
                            (creatureBase.Faction == TargetCreatureBase.Faction || castingCreature.hateManager.GetCreatureHateInfo(creatureBase) != null) &&
                            creatureBase.CanSeeMe(castingCreature))
                        {
                            foundCreature = true;
                            creaturesToEffect.Add(creatureBase);
                        }
                    }

                    if (foundCreature == true)
                        animateMapItems.Add(mapItem);
                }
            }

            List<CreatureBase> creatureBasesToUpdate = new List<CreatureBase>();
            List<MapItem> mapItemsToUpdate = new List<MapItem>();

            //Damage them later, damaging them can cause creatures to be removed from the tile which will break the above iteration
            foreach (CreatureBase creaturebase in creaturesToEffect)
            {
                //If we're attacking a player, and we dont have a flag on them, give them a flag on us.
                if (creaturebase is Character &&
                    castingCreature is Character &&
                    creaturebase != castingCreature &&
                    castingCreature.hateManager.GetCreatureHateInfo(creaturebase) == null &&
                    spellIcon.Offensive == true)
                {
                    Character charToAttack = (Character)creaturebase;
                    if (charToAttack.friendsManager.hasNoSDFlag(CastingCharacterID) == false)
                    {
                        if (creaturebase.hateManager.GetCreatureHateInfo(castingCreature) == null)
                        {
                            creaturebase.SendMessage("You have been ATTACKED by " + castingCreature.Name + "!", "damaged");
                            creaturebase.PlaySound("Ding", creaturebase.MapX, creaturebase.MapY);

                            creaturebase.hateManager.UpdateList(castingCreature, 0);


                            charToAttack.AddMapItem(castingCreature.currentMapItem);
                        }
                        else
                            creaturebase.hateManager.UpdateList(castingCreature, 0);
                    }
                }

                int Damage = Managers.GameHandler.random.Next(DamageLow, DamageHigh + 1);
                Damage = SkillManager.AdjustForCombat(CastingCreatureLevel, Damage, CastingCreatureInt);

                int ActualDamage = creaturebase.CalculateGetSpellDamagePerResists(Damage, spellIcon.Skill);
                int absorbedDamage;
                creaturebase.InflictSpellDamage(ActualDamage, CastingCharacterID, CastingCreatureGUID, spellIcon.Skill, out absorbedDamage);

                creaturebase.Update_Character();

                ActualDamage = ActualDamage - absorbedDamage;

                creatureBasesToUpdate.Add(creaturebase);

                if (castingCreature is Character)
                {
                    Character character = (Character)castingCreature;

                    Message message = new Message();
                    message.CreatureID = character.CreatureID;
                    message.Type = "spelloffense";
                    message.Text = "You shock " + creaturebase.Name + "! (" + ActualDamage.ToString() + ")";

                    if (absorbedDamage != 0)
                        message.Text = message.Text + " ABSORBED " + absorbedDamage.ToString();

                    character.AddMessage(message);
                }
                if (creaturebase is Character && creaturebase != castingCreature)
                {
                    Character character = (Character)creaturebase;

                    Message message = new Message();
                    message.CreatureID = character.CreatureID;
                    message.Type = "spelloffense";
                    message.Text = castingCreature.Name + " shocks you! (" + ActualDamage.ToString() + ")";

                    if (absorbedDamage != 0)
                        message.Text = message.Text + " ABSORBED " + absorbedDamage.ToString();

                    character.AddMessage(message);
                }

                if (creaturebase.HP > 1)
                {
                    int result = Managers.GameHandler.random.Next(1, 101);
                    if (result > 50 && creaturebase.buffManager.IsStunned() == false)
                    {
                        bool isImmune = false;
                        if (creaturebase is Creature)
                        {
                            Creature targetCrit = (Creature)creaturebase;
                            if (targetCrit.isImmune("Stun") == true)
                            {
                                castingCreature.SendMessage(creaturebase.Name + " is immune to " + spellIcon.Name + "'s stun effect!", "spelldefense");
                                isImmune = true;
                            }
                        }
                        if (isImmune == false)
                        {
                            Spell_Stun buff = new Spell_Stun();
                            buff.saveBuff = false;
                            if (buff.tryResist(this.spellIcon, CastingCreatureLevel, CastingCreatureInt, CastingCreatureWis, creaturebase) == true)
                            {
                                if (creaturebase != castingCreature)
                                    castingCreature.SendMessage(creaturebase.Name + " resists " + spellIcon.Name + "!", "spelldefense");

                                creaturebase.SendMessage("You resist " + castingCreature.Name + "'s " + spellIcon.Name + "!", "spelloffense");
                            }
                            else
                            {
                                Buff oldLight = creaturebase.buffManager.GetBuffByStackType("Lightning");
                                if (oldLight != null)
                                    oldLight.RemoveSpell(false, false);

                                CreatureBase cb = creaturebase;
                                buff.Resume(cb, this.spellIcon, 5, CastingCreatureLevel, CastingCharacterID, CastingCreatureInt, CastingCreatureWis, -1, null);
                                cb.buffManager.UpdateBuffs();
                            }
                        }
                    }
                }
                //Creature is dead, record the map item.
                else if (mapItemsToUpdate.Contains(creaturebase.currentMapItem) == false)
                    mapItemsToUpdate.Add(creaturebase.currentMapItem);
            }

            List<Character> charactersWithin8 = castingCreature.currentMapItem.getCharactersWithin8();
            foreach (Character character in charactersWithin8)
            {
                foreach (MapItem mapItem in animateMapItems)
                    character.AddAnimation(spellIcon.FieldImageURL, TargetCreatureBase.MapID, mapItem.MapX, mapItem.MapY, 1);

                character.AddMapItems(mapItemsToUpdate, false);

                foreach (CreatureBase cb in creatureBasesToUpdate)
                {
                    if (mapItemsToUpdate.Contains(cb.currentMapItem) == false)
                        character.AddCreatureBase(cb);
                }
            }
        }

        public void InstantCast(CreatureBase castingCreature, CreatureBase targetCreatureBase, SpellIcon _spellIcon, int castLevel)
        {
            if (base.InitializeInstantCast(castingCreature, targetCreatureBase, _spellIcon, castLevel, false) == false)
                return;

            mainCast(castingCreature);
        }
    }
}
